Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hooks: Dispatch all heartbeat events as hooks actions #11781

Merged
merged 7 commits into from
Jan 4, 2019

Conversation

aduth
Copy link
Member

@aduth aduth commented Nov 12, 2018

Related: #4217

This pull request seeks to enhance our handling of heartbeat-to-hooks upgrade to consistently fire all heartbeat events as actions. In addition to promoting consistency, it enables us to refactor the PostLockedModal to avoid having the editor module depend on jQuery.

Testing instructions:

Verify there are no regressions in the behavior of post locking by repeating testing instructions from #4217.

Verify there are no regressions in other existing usage of upgrade heartbeat events, i.e. the api-fetch nonce middleware.

@aduth aduth added [Type] Code Quality Issues or PRs that relate to code quality [Package] Hooks /packages/hooks labels Nov 12, 2018
@aduth aduth mentioned this pull request Nov 12, 2018
3 tasks
@youknowriad
Copy link
Contributor

I noticed two regressions.

This error message was triggered on the original editor when I "took over editing".

screen shot 2018-11-13 at 09 39 47

I also noticed that releasing a post is not working properly (I've used Firefox to release the post, I did'tn try Chrome). So even if the original author is not editing the post anymore, the second author see the lock modal.

@aduth
Copy link
Member Author

aduth commented Nov 13, 2018

I don't suppose we have automated testing for this feature then? 😅

@youknowriad
Copy link
Contributor

I actually wrote the e2e tests and committed them in the original PR but had to revert them because I was not able to push them to a stable state.

1f53d95

@aduth
Copy link
Member Author

aduth commented Nov 13, 2018

I pushed two commits which should resolve your two issues:

  • Due to how withGlobalEvents is implemented, it must be the immediate wrapping higher-order component. This is why the beforeunload behavior to release the lock was not previously working, now resolved by 9d2c3ef.
    • Aside: We should consider integrating something like hoist-non-react-statics in the createHigherOrderComponent helper. This would have prevented the issue from occurring since the releasePostLock method would have been hoisted to be available to withGlobalEvents. I had thought we might have considered this once in the past, cc @gziolo .
  • Binding to a jQuery event will always provide the event as the first argument in the callback. This is not true in the upgraded action. Thus, what we were previously considering as the second argument data now becomes the first, resolved in ca8a291.

@youknowriad youknowriad modified the milestones: 4.4, 4.5 Nov 14, 2018
@gziolo gziolo added the [Priority] Low Used to indicate that the issue at hand isn't a top priority to address and can be handled later label Nov 19, 2018
@aduth aduth force-pushed the remove/editor-jquery branch from 9d2c3ef to eed0bd8 Compare November 19, 2018 16:13
@catehstn
Copy link

Moving this to 4.6, no rush to get it in today.

@catehstn catehstn modified the milestones: 4.5, 4.6 Nov 19, 2018
@mtias mtias modified the milestones: 4.6, 4.7 Nov 22, 2018
'heartbeat-nonces-expired',
].join( ' ' ), function( event ) {
var actionName = event.type.replace( /-/g, '.' );
wp.hooks.doAction.apply( null, [ actionName ].concat( [].slice.call( arguments, 1 ) ) );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add a comment here along the lines of

Suggested change
wp.hooks.doAction.apply( null, [ actionName ].concat( [].slice.call( arguments, 1 ) ) );
// Heartbeat API events have different number of arguments passed to them,
// so we need to destructure them to pass them to the proper action hook.
wp.hooks.doAction.apply( null, [ actionName ].concat( [].slice.call( arguments, 1 ) ) );

I wish I could have found a link explaining the different Heartbeat action hooks and their payload to add to the comment, but I couldn't.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wish I could have found a link explaining the different Heartbeat action hooks and their payload to add to the comment, but I couldn't.

There's no written documentation, but there's a code file from which the original list was obtained. We could potentially include this (will have to find it once more).

@@ -30,17 +30,30 @@ class PostLockedModal extends Component {
}

componentDidMount() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we consider the heartbeat.error event/hook as well? I'm not that familiar with the heartbeat API so I don't know in what specific situation that would be fired that heartbeat.tick doesn't cover. At first sight, it seems sensible. If that makes sense, I'm happy if we do that in a follow-up PR and I can prepare one.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we consider the heartbeat.error event/hook as well? I'm not that familiar with the heartbeat API so I don't know in what specific situation that would be fired that heartbeat.tick doesn't cover. At first sight, it seems sensible. If that makes sense, I'm happy if we do that in a follow-up PR and I can prepare one.

Maybe, but as you alluded, I'm more concerned on an in-place-compatible refactoring here; no additions of behavior.

*/
getHookNamePrefix() {
const { instanceId } = this.props;
return 'core/editor/post-locked-modal-' + instanceId + '-heartbeat';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this namespace better. Yet I find the heartbeat-{send/tick} repetition not necessary as it is already in the action name. How about:

Suggested change
return 'core/editor/post-locked-modal-' + instanceId + '-heartbeat';
return 'core/editor/post-locked-modal-' + instanceId;

Copy link
Member

@oandregal oandregal Nov 29, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, that would be more in line with the other existing heartbeat use case (nonce middleware) where we use core/api-fetch/create-nonce-middleware.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure 👍 Since the function name needs to be provided when calling removeAction anyways (the theoretical need for this in the first place), it's arguably redundant.

jQuery( document )
.on( 'heartbeat-send.refresh-lock', this.sendPostLock )
.on( 'heartbeat-tick.refresh-lock', this.receivePostLock );
addAction( 'heartbeat.send', hookNamePrefix + '-send', this.sendPostLock );
Copy link
Member

@oandregal oandregal Nov 29, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mentioned here, how about:

Suggested change
addAction( 'heartbeat.send', hookNamePrefix + '-send', this.sendPostLock );
addAction( 'heartbeat.send', hookNamePrefix, this.sendPostLock );

Copy link
Member

@oandregal oandregal Nov 29, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess, the Suggest change beta feature doesn't like multicomment lines :/ Edited.

.off( 'heartbeat-tick.refresh-lock', this.receivePostLock );
const hookNamePrefix = this.getHookNamePrefix();

removeAction( 'heartbeat.send', hookNamePrefix + '-send' );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
removeAction( 'heartbeat.send', hookNamePrefix + '-send' );
removeAction( 'heartbeat.send', hookNamePrefix );

const hookNamePrefix = this.getHookNamePrefix();

removeAction( 'heartbeat.send', hookNamePrefix + '-send' );
removeAction( 'heartbeat.tick', hookNamePrefix + '-tick' );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
removeAction( 'heartbeat.tick', hookNamePrefix + '-tick' );
removeAction( 'heartbeat.tick', hookNamePrefix );

.on( 'heartbeat-send.refresh-lock', this.sendPostLock )
.on( 'heartbeat-tick.refresh-lock', this.receivePostLock );
addAction( 'heartbeat.send', hookNamePrefix + '-send', this.sendPostLock );
addAction( 'heartbeat.tick', hookNamePrefix + '-tick', this.receivePostLock );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
addAction( 'heartbeat.tick', hookNamePrefix + '-tick', this.receivePostLock );
addAction( 'heartbeat.tick', hookNamePrefix, this.receivePostLock );

Copy link
Member

@oandregal oandregal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've left some minor comments that I'd be happy if were addressed. Not a blocker.

This is working as expected. Worth noting that in my testing, the autosave network request on receivePostLock has failed both in this PR and in master. I will follow up with an issue for that if there isn't one already.

@oandregal
Copy link
Member

Worth noting that in my testing, the autosave network request on receivePostLock has failed both in this PR and in master. I will follow up with an issue for that if there isn't one already.

No longer can repro the issue 🤷‍♂️

@aduth aduth modified the milestones: 4.7, 4.8 Dec 8, 2018
@aduth aduth force-pushed the remove/editor-jquery branch from eed0bd8 to 75793f2 Compare December 11, 2018 21:52
@youknowriad youknowriad modified the milestones: 4.8, 4.9 Dec 19, 2018
@aduth aduth force-pushed the remove/editor-jquery branch from 75793f2 to 454c93f Compare January 3, 2019 21:15
@aduth aduth force-pushed the remove/editor-jquery branch from 454c93f to e1c3c0e Compare January 4, 2019 14:09
@aduth aduth merged commit 95edac1 into master Jan 4, 2019
@aduth aduth deleted the remove/editor-jquery branch January 4, 2019 14:54
@aduth
Copy link
Member Author

aduth commented Jan 28, 2019

This needs a Trac ticket, since it must be changed in core in time for 5.2 (5.1 aligns to Gutenberg 4.8, so the version prior to what included this change).

(Will set a reminder for myself to create one)

@aduth
Copy link
Member Author

aduth commented Jan 29, 2019

This needs a Trac ticket, since it must be changed in core in time for 5.2 (5.1 aligns to Gutenberg 4.8, so the version prior to what included this change).

It appears this should already be accounted for, as part of the following changeset:

https://core.trac.wordpress.org/changeset/43939

But then it also occurs to me that Gutenberg's proxying may now actually cause the action to be handled twice, once for the native doAction and a second time for the jQuery event proxying.

If the above changeset was included as part of WordPress 5.0, it should stand to reason that we might not need the jQuery event proxying at all?

youknowriad pushed a commit that referenced this pull request Mar 6, 2019
* Framework: Dispatch all heartbeat events as actions

* Editor: Send PostLockModal lock request via XHR

* Editor: Use hooks for PostLockedModal heartbeat handling

* Framework: Update package-lock.json per jQuery dependency drop

* Editor: Remove unsupported event object from action callback

* Editor: Assure withGlobalEvents is last to wrap component

Since it tests for static method on which to call

* Editor: Reuse hook name across disparate hooks
youknowriad pushed a commit that referenced this pull request Mar 6, 2019
* Framework: Dispatch all heartbeat events as actions

* Editor: Send PostLockModal lock request via XHR

* Editor: Use hooks for PostLockedModal heartbeat handling

* Framework: Update package-lock.json per jQuery dependency drop

* Editor: Remove unsupported event object from action callback

* Editor: Assure withGlobalEvents is last to wrap component

Since it tests for static method on which to call

* Editor: Reuse hook name across disparate hooks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] Hooks /packages/hooks [Priority] Low Used to indicate that the issue at hand isn't a top priority to address and can be handled later [Type] Code Quality Issues or PRs that relate to code quality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants